package com.server;

import java.awt.Color;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
import java.util.Map.Entry;

public class RoomHandler {
	private static final Color[]					COLOR_REPO	= { Color.white, Color.pink, Color.red, Color.green,
			Color.orange, Color.yellow, Color.lightGray, Color.blue, Color.cyan, Color.magenta };

	private Map<Integer, String>					rooms;
	private Map<Integer, String>					pws;
	private Map<Integer, LinkedList<Integer>>		members;
	private Map<Integer, HashMap<Integer, Color>>	colors;
	private int										id;

	/**
	 * Creates a new <code>RoomHandler</code> that takes care of all rooms. It handles the members of each room and
	 * their current colors.
	 */
	public RoomHandler()
	{
		rooms = new HashMap<Integer, String>();
		pws = new HashMap<Integer, String>();
		members = new HashMap<Integer, LinkedList<Integer>>();
		colors = new HashMap<Integer, HashMap<Integer, Color>>();
		id = 0;
	}

	/**
	 * Returns the id of each room mapped to the name of the room.
	 * 
	 * @return a map of <code>ID->String</code> where room id is mapped to room name
	 */
	public Map<Integer, String> getRooms()
	{
		return rooms;
	}

	public int createRoom(String name, String sha1Password)
	{
		if (rooms.containsValue(name))
		{
			return -1;
		}
		rooms.put(id, name);
		pws.put(id, sha1Password);
		members.put(id, new LinkedList<Integer>());
		id++;
		System.out.println("Spawned room:\t" + name + " id: " + id + " pw: .." + sha1Password);
		return id - 1;
	}

	public int[] getMembersOfRoom(int roomId)
	{
		if (members.get(roomId) == null)
		{
			System.out.println("Invalid ID");
			return null;
		}
		LinkedList<Integer> list = members.get(roomId);
		int[] toReturn = new int[list.size()];
		Iterator<Integer> it = list.iterator();
		for (int i = 0; i < toReturn.length; i++)
		{
			toReturn[i] = it.next();
		}
		return toReturn;
	}

	private boolean roomHasColor(int roomId, Color c)
	{
		for (Entry<Integer, Color> e : colors.get(roomId).entrySet())
		{
			if (e.getValue().equals(c))
			{
				return true;
			}
		}
		return false;
	}

	public Color getColor(int roomId, int userId)
	{
		if (colors.get(roomId) == null)
		{
			System.out.println("Illegal roomId (" + roomId + ") in getColor in RoomHandler");
			return null;
		}
		if (colors.get(roomId).get(userId) == null)
		{
			System.out.println("userId (" + userId + ") hasnt been assigned a color in roomId (" + roomId
					+ ") in getColor in RoomHandler");
		}
		return colors.get(roomId).get(userId);
	}

	private Color assignColor(int roomId, int userId)
	{
		HashMap<Integer, Color> map = null;
		if (colors.get(roomId) == null)
		{
			map = new HashMap<Integer, Color>();
			colors.put(roomId, map);
		} else
		{
			map = colors.get(roomId);
		}
		Color c = null;
		do
		{
			c = COLOR_REPO[(int) (Math.random() * COLOR_REPO.length)];
		} while (roomHasColor(roomId, c));
		map.put(userId, c);
		return c;
	}

	public boolean join(int roomId, int userId, String password)
	{
		if (pws.get(roomId) == null)
		{
			System.out.println("joining invalid room");
			return false;
		}
		if (pws.get(roomId).equals(password))
		{
			members.get(roomId).push(userId);
			assignColor(roomId, userId);
			return true;
		}
		return false;
	}

	public boolean leave(int roomId, int userId)
	{
		if (pws.get(roomId) == null)
		{
			System.out.println("leaving invalid room");
			return false;
		}
		if (members.get(roomId).contains(userId))
		{
			members.get(roomId).remove(userId);
			return true;
		}
		return false;
	}

	public int findRoomOf(int clientId)
	{
		for (Entry<Integer, LinkedList<Integer>> e : members.entrySet())
		{
			if (e.getValue().contains(clientId))
			{
				return e.getKey();
			}
		}
		return -1;
	}

}
